<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>状态模式(state pattern)</title>
    <!-- 
  状态模式（State Pattern）是一种行为型设计模式，它允许对象在其内部状态变化时改变其行为。状态模式将状态的相关行为封装在状态类中，使得状态的变化和相关逻辑的实现分离。通过这种方式，状态模式可以使得对象的行为在不同状态下表现得不同，避免了使用大量的条件语句来处理状态转换。

  ### 状态模式的主要组成部分

  1. **上下文（Context）**：持有一个状态对象的引用，并定义与状态相关的操作。上下文类通常会委托状态对象来处理请求。
  2. **状态接口（State）**：定义一个接口，声明与上下文相关的状态行为。
  3. **具体状态（Concrete State）**：实现状态接口，定义具体的状态行为。

  ### 状态模式的优点

  1. **简化代码**：通过将状态相关的行为封装到状态类中，避免了大量的条件语句，使代码更加简洁和清晰。
  2. **增强可维护性**：状态的变化和相关逻辑分离，使得状态的管理和维护更加容易。
  3. **动态切换状态**：可以在运行时动态改变对象的状态，增强了系统的灵活性。

  ### 状态模式的缺点

  1. **增加类的数量**：每个状态都需要一个具体的状态类，可能会导致类的数量增加。
  2. **状态管理复杂性**：在某些情况下，状态之间的转移逻辑可能会变得复杂，导致管理困难。

  ### 示例代码

  以下是一个使用状态模式的简单示例，展示一个简单的电梯系统。

  #### 1. 状态接口（State）


  ```javascript
  class ElevatorState {
      openDoor() {
          throw new Error("此方法必须被实现。");
      }

      closeDoor() {
          throw new Error("此方法必须被实现。");
      }

      goUp() {
          throw new Error("此方法必须被实现。");
      }

      goDown() {
          throw new Error("此方法必须被实现。");
      }
  }
  ```

  #### 2. 具体状态（Concrete States）


  ```javascript
  class Elevator {
      constructor() {
          this.state = new ClosedState(this); // 初始状态为关闭
      }

      setState(state) {
          this.state = state; // 设置当前状态
      }

      openDoor() {
          return this.state.openDoor();
      }

      closeDoor() {
          return this.state.closeDoor();
      }

      goUp() {
          return this.state.goUp();
      }

      goDown() {
          return this.state.goDown();
      }
  }

  class ClosedState extends ElevatorState {
      constructor(elevator) {
          super();
          this.elevator = elevator;
      }

      openDoor() {
          console.log("门已打开。");
          this.elevator.setState(new OpenState(this.elevator));
      }

      closeDoor() {
          console.log("门已经关闭。");
      }

      goUp() {
          console.log("电梯正在上升。");
      }

      goDown() {
          console.log("电梯正在下降。");
      }
  }

  class OpenState extends ElevatorState {
      constructor(elevator) {
          super();
          this.elevator = elevator;
      }

      openDoor() {
          console.log("门已经打开。");
      }

      closeDoor() {
          console.log("门已关闭。");
          this.elevator.setState(new ClosedState(this.elevator));
      }

      goUp() {
          console.log("无法上升，门是开的。");
      }

      goDown() {
          console.log("无法下降，门是开的。");
      }
  }
  ```

  #### 3. 使用示例


  ```javascript
  const elevator = new Elevator();

  elevator.openDoor(); // 输出: "门已打开。"
  elevator.goUp();     // 输出: "无法上升，门是开的。"
  elevator.closeDoor(); // 输出: "门已关闭。"
  elevator.goUp();     // 输出: "电梯正在上升。"
  ```

  ### 总结

  状态模式是一种有效的设计模式，适用于需要根据对象状态变化来改变其行为的场景。通过将状态相关的行为封装到状态类中，状态模式提高了代码的可维护性和可读性。在设计系统时，合理运用状态模式可以简化状态管理逻辑，增强系统的灵活性。
  -->
  </head>
  <body>
    <script>
      // 状态模式是一种行为设计模式，它允许对象在其内部状态改变时改变其行为。状态模式将对象的行为包装在不同的状态对象中，每个状态对象对应一种状态，并且可以相互转换。

      class State {
        constructor(color) {
          this.color = color;
        }

        handle(context) {
          console.log(`当前状态为：${this.color}`);
          context.setState(this.color);
        }
      }

      class Context {
        constructor() {
          this.state = null;
        }

        setState(state) {
          this.state = state;
        }

        getState() {
          return this.state;
        }
      }

      // 测试代码
      let context = new Context();

      let greed = new State("greed");
      let yellow = new State("yellow");
      let red = new State("red");

      greed.handle(context); // 输出: "当前状态为：greed"
      console.log(context.getState()); // 输出: "greed"

      yellow.handle(context); // 输出: "当前状态为：yellow"
      console.log(context.getState());

      red.handle(context); // 输出: "当前状态为：red"
      console.log(context.getState());
    </script>
  </body>
</html>
